﻿using Data;
using Hero;
using Infrastructure.States;
using Level;
using Level.Bonuses;
using Level.Enemies;
using Services.Progress;
using Services.StaticData;
using UnityEngine;

namespace Factory
{
    public class LootFactory : ILootFactory
    {
        private readonly IProgressService _progressService;
        private readonly GameStateMachine _stateMachine;
        private readonly IStaticDataService _staticDataService;
        private GameSceneData _data;
        private HeroState _state;
        private HeroScore _heroScore;
        private HeroShoot _heroShoot;
        private HeroHealth _heroHealth;
        private HeroReload _heroReload;
        private LevelStaticData _levelData;

        public LootFactory(IProgressService progressService,
            GameStateMachine stateMachine, IStaticDataService staticDataService)
        {
            _progressService = progressService;
            _stateMachine = stateMachine;
            _staticDataService = staticDataService;
        }

        public void InitGameData(HeroHealth health, HeroReload reload, HeroScore score, HeroShoot shoot)
        {
            _data = _progressService.Progress.GameSceneData;
            _state = _progressService.Progress.HeroState;
            _heroHealth = health;
            _heroReload = reload;
            _heroScore = score;
            _heroShoot = shoot;
            _levelData = _staticDataService.Level;
        }

        public void CreateExit(Vector3 at)
        {
            var obj = Object.Instantiate(_levelData.ExitPrefab, at, Quaternion.identity);
            _data.Exit = obj;
            obj.TryGetComponent<Exit>(out var exit);
            exit.Construct(_stateMachine, _data);
        }

        public void CreateGunBonus(Vector3 at)
        {
            var obj = Object.Instantiate(_levelData.GunPrefab, at, Quaternion.identity);
            _data.LootPieces.Add(obj);
            obj.TryGetComponent<Gun>(out var gun);
            gun.Value = _levelData.GunValue;
            gun.Construct(_data, _state, _heroScore, _heroShoot);
        }

        public void CreateLifeBonus(Vector3 at)
        {
            var obj = Object.Instantiate(_levelData.LifePrefab, at, Quaternion.identity);
            _data.LootPieces.Add(obj);
            obj.TryGetComponent<Life>(out var life);
            life.Value = _levelData.LifeValue;
            life.Construct(_data, _heroScore, _heroHealth);

        }

        public void CreateAmmoBonus(Vector3 at)
        {
            var obj = Object.Instantiate(_levelData.AmmoPrefab, at, Quaternion.identity);
            _data.LootPieces.Add(obj);
            obj.TryGetComponent<Ammo>(out var ammo);
            ammo.Value = _levelData.AmmoValue;
            ammo.Construct(_data, _state, _heroScore, _heroReload);
        }

        public void CreateBomb(Vector3 at)
        {
            var obj = Object.Instantiate(_levelData.BombPrefab, at, Quaternion.identity);
            _data.LootPieces.Add(obj);
            obj.TryGetComponent<Bomb>(out var bomb);
            bomb.Value = _levelData.BombValue;
            obj.TryGetComponent<BombHealth>(out var health);
            health.Max = _levelData.BombHealth.Increase(_data.CurrentLevel - 1);
            obj.TryGetComponent<BombDamage>(out var damage);
            damage.Radius = _levelData.BombRadius.Increase(_data.CurrentLevel - 1);
            damage.Damage = _levelData.BombDamage.Increase(_data.CurrentLevel - 1);
            obj.TryGetComponent<BombMove>(out var move);
            move.Construct(_data.Hero.transform);
            obj.TryGetComponent<BombDeath>(out var death);
            death.Construct(_data, _heroScore);
            obj.TryGetComponent<BombVisual>(out var visual);
            visual.Construct(_data);
        }
    }
}